﻿#if USING_XLUA
using System;
using XLua;
using UnityEngine;
using com.susi.util;
using IDisposaEventer = com.susi.util.IDisposaEventer;

namespace com.susi.Lua {
    public class LuaManager : MonoBehaviour, IDisposaEventer, IDisposaEventer<LuaManager> {
        public static LuaManager Instance { get; private set; }
        private const string     _Name = nameof(LuaManager);
        public static string     Name       => _Name;
        public        bool       IsLoaded   { get; private set; }
        public        bool       IsDisposed { get; private set; }
        public        LuaEnv     luaEnv     { get; private set; }
        private       float      lastGCTime = 0;
        private const float      GCInterval = 1; //1 second 

        public event Action             onDisposingEvent;
        public event Action<LuaManager> onDisposingTEvent;

        private LuaManager() { }

        private void Awake()
        {
            if (Instance != null) {
                if(Instance!=this) Destroy(gameObject);
                return;
            }
            DontDestroyOnLoad(gameObject);
            Instance = this;
            Init();
        }

        public static void Install()
        {
            if (Instance == null) {
                var go = new GameObject(_Name);
                go.AddComponent<LuaManager>();
            }
        }

        private void Init()
        {
            luaEnv = new LuaEnv();
            //CustomLoader localrresloader = (ref string v) =>
            //{
            //    byte[] LocalTryGet(string filepath)
            //    {
            //        if (File.Exists(filepath))
            //        {
            //            return File.ReadAllBytes(filepath);
            //        }
            //        else
            //        {
            //            return null;
            //        }
            //    }
            //    if (!v.EndsWith(".lua", true, System.Globalization.CultureInfo.CurrentCulture))
            //        v += ".lua";
            //    return LocalTryGet(Application.dataPath + "/Resource/Lua/" + v);
            //};
            //luaEnv.AddLoader(localrresloader);
            var res = Resources.Load<TextAsset>("Lua/OnLuaManagerInstalling");
            if (res) luaEnv.DoString(res.text);
            IsLoaded = true;
        }

        private void Update()
        {
            if (Time.time - lastGCTime > GCInterval) {
                luaEnv?.Tick();
                lastGCTime = Time.time;
            }
        }

        public void Dispose()
        {
            if (IsDisposed) return;
            IsDisposed = true;
            onDisposingEvent?.Invoke();
            onDisposingTEvent?.Invoke(this);
            onDisposingEvent  = null;
            onDisposingTEvent = null;
            luaEnv?.Dispose();
            Destroy(gameObject);
        }

        private void OnDestroy()
        {
            Dispose();
        }
    }
}
#endif